import 'dart:convert';

import 'package:im_app/im/pojo/ImPojo.dart';
import 'package:logger/logger.dart';
import 'package:sqflite/sqflite.dart';

import '../util/DateUtil.dart';
import '../util/ImSingleton.dart';
import '../util/MapUtil.dart';
import 'BaseDao.dart';

class ImDepartmentDao extends BaseDao {

  final _logger = Logger(
    printer: PrettyPrinter(),
  );

  Future<List<ImDepartment>> getByIds(List<String> codeList) async {
    Database? database = getDatabase(); //ImSingleton.getInstance()?.dataBase;
    String param = codeList.map((e) => "\"$e\"").join(",");
    String sql = "select * from im_department where code in ($param)";
    List<Map<String, Object?>>? list = await database?.rawQuery(sql, []);
    List<ImDepartment> result = list != null ? list.map((map){return this._toImDepartment(map);}).toList() : [];
    return result;
  }

  Future<List<ImDepartment>> getAll() async {
    Database? database = getDatabase(); //ImSingleton.getInstance()?.dataBase;
    String sql = "select * from im_department where status = ? order by id";
    List<Map<String, Object?>>? list = await database?.rawQuery(sql, [ImDepartmentStatus.enable.value]);
    List<ImDepartment> result = list != null ? list.map((map){return this._toImDepartment(map);}).toList() : [];
    return result;
  }

  Future<void> inserts(List<ImDepartment> departments) async {
    if (departments.length < 1) return;
    Database? database = ImSingleton.getInstance().dataBase;
    Batch? batch = database?.batch();
    for (var d in departments) {
      var data = toMap(d);
      batch?.insert("im_department", data);
    }
    List<Object?>? list = await batch?.commit();
    _logger.i("batch json: " + jsonEncode(list));
  }

  Future<void> updates(List<ImDepartment> departments) async {
    if (departments.length < 1) return;
    Database? database = getDatabase(); //ImSingleton.getInstance()?.dataBase;
    Batch? batch = database?.batch();
    for (var d in departments) {
      var data = toMap(d);
      batch?.update("im_department", data, where: "code = ?", whereArgs: [data['code']]);
    }
    List<Object?>? list = await batch?.commit();
    _logger.i("json: " + jsonEncode(list));
  }

  Map<String, Object?> toMap(ImDepartment department) {
    Map<String, Object?> map = {};
    map['currentUserId'] = department.currentUserId;
    map['code'] = department.code;
    map['description'] = department.description;
    map['name'] = department.name;
    map['parentCode'] = department.parentCode;
    map['managerUserId'] = department.managerUserId;
    map['otherManagerUserIds'] = department.otherManagerUserIds;
    map["status"]= department.status?.value;
    map['ext1'] = department.ext1;
    map['ext2'] = department.ext2;
    map['createTime'] = DateUtil.formatDate(department.createTime);
    map['updateTime'] = DateUtil.formatDate(department.updateTime);

    return map;
  }

  ImDepartment _toImDepartment(Map<String, Object?> data) {
    var imDepartment = ImDepartment(id: MapUtil.getInt(data, 'id'),
        currentUserId: MapUtil.getString(data, 'currentUserId'),
        code: MapUtil.getString(data, 'code'),
        name: MapUtil.getString(data, 'name'),
        description: MapUtil.getStringOrNull(data, 'description'),
        parentCode : MapUtil.getStringOrNull(data, 'parentCode'),
        managerUserId : MapUtil.getStringOrNull(data, 'managerUserId'),
        otherManagerUserIds : MapUtil.getStringOrNull(data, 'otherManagerUserIds'),
        otherManagerUserIdSet : MapUtil.getSetOrNull<String>(data, 'otherManagerUserIdSet', (s){ return s.toString();}),
        status:ImDepartmentStatus.ofValue(MapUtil.getInt(data, "status")),
        ext1 : MapUtil.getStringOrNull(data, 'ext1'),
        ext2 : MapUtil.getStringOrNull(data, 'ext2'),
    );
    imDepartment.createTime = MapUtil.getDate(data, 'createTime');
    imDepartment.updateTime = MapUtil.getDate(data, 'updateTime');
    return imDepartment;
  }
}
